#include "leasesmodel.h"
#include <QDebug>

LeasesModel::LeasesModel(QObject *parent) :
    QAbstractTableModel(parent),
    m_last_row(-1)
{
}


void LeasesModel::load_data(const LeasesModel::Filter *p_filter)
{
    mqvl_indexes.clear();
    qDebug()<<"loading leases model data...";
    if(p_filter == NULL)
    {
        mqvl_indexes = mp_dbms->get_db(LAKDB_LEASES)->findDataRange(FLD_LS_NUM);
        mqvl_indexes.removeFirst();
        qDebug()<<"leases model. data loaded. size:"<<mqvl_indexes.size();
        return;
    }
    QVariant qv_req;
    QVariantList qvl_streets_indexes;
    QVariantList qvl_h_indices;
    QVariantList qvl_ap_indices;
    QVariantList qvl_ten_indices;
    SleeQHash_Constrain *p_constr;

    //filter streets
    if(p_filter->mqstr_street.size())
    {
        qv_req = p_filter->mqstr_street;
        qvl_streets_indexes = mp_dbms->get_db(LAKDB_STREETS)->findRelevantData(FLD_STDB_NAME,qv_req);
        if(!qvl_streets_indexes.size()) return;
    }
    qv_req.clear();
    SleeQHash_Constrain h_num_constr;
    p_constr = NULL;
    qDebug()<<"streets found"<<qvl_streets_indexes.size();
    //filter houses
    if(p_filter->mqstr_house.size())
    {
        qv_req = p_filter->mqstr_house;
        h_num_constr.append(qv_req, FLD_HSDB_NAME);
        h_num_constr.set_process_string("$0#  = $0%");
        p_constr = &h_num_constr;
    }
    if(qvl_streets_indexes.size())
    {

        foreach(QVariant qv_s_index, qvl_streets_indexes)
        {
            QVariantList qvl_h_temp = mp_dbms->get_db(LAKDB_HOUSES)->findDataEq(FLD_HSDB_STINDEX,qv_s_index,NULL,p_constr);
            qvl_h_indices.append(qvl_h_temp);
        }
        if(!qvl_h_indices.size()) return;
    }
    else
    {
        if(qv_req.isValid())
        {
            qvl_h_indices = mp_dbms->get_db(LAKDB_HOUSES)->findDataEq(FLD_HSDB_NAME, qv_req);
            if(!qvl_h_indices.size()) return;
        }
    }
    qDebug()<<"houses found"<<qvl_h_indices.size();
    //filter apartments
    qv_req.clear();
    p_constr = NULL;
    SleeQHash_Constrain ap_num_constr;
    if(p_filter->mqstr_ap_num.size())
    {
        qv_req = p_filter->mqstr_ap_num;
        ap_num_constr.append(qv_req, FLD_APDB_NUMBER);
        ap_num_constr.set_process_string("$0#  = $0%");
        p_constr = &ap_num_constr;

    }
    if(qvl_h_indices.size())
    {
        foreach(QVariant qv_h_index, qvl_h_indices)
        {
            QVariantList qvl_ap_temp = mp_dbms->get_db(LAKDB_APARTMENTS)->findDataEq(FLD_APDB_HSINDEX, qv_h_index, NULL,p_constr);
            qvl_ap_indices.append(qvl_ap_temp);
        }
        if(!qvl_ap_indices.size()) return;
    }
    else
    {
        if(qv_req.isValid())
        {
            qvl_ap_indices = mp_dbms->get_db(LAKDB_APARTMENTS)->findDataEq(FLD_APDB_NUMBER, qv_req);
            if(!qvl_ap_indices.size()) return;
        }
    }
    qDebug()<<"apartments found"<<qvl_ap_indices.size();

    //filter tenants
    qv_req.clear();
    p_constr = NULL;
    if(p_filter->mqstr_ten_fam.size())
    {
        qv_req = p_filter->mqstr_ten_fam;
        qvl_ten_indices = mp_dbms->get_db(LAKDB_TENANTS)->findRelevantData(FLD_TEN_FAM,qv_req);
    }
    qDebug()<<"tenants found"<<qvl_ten_indices.size();

    //by ap filtering
    if(qvl_ap_indices.size())
    {
        QVariantList qvl_ls_indices_pre;
        foreach(QVariant qv_a_index, qvl_ap_indices)
        {
            QVariantList qvl_ls_temp;
            qvl_ls_temp = mp_dbms->get_db(LAKDB_LEASES)->findDataEq(FLD_LS_AINDEX, qv_a_index);
            qvl_ls_indices_pre.append(qvl_ls_temp);
        }

        if(qvl_ten_indices.size())
        {
            foreach(QVariant qv_ls_index, qvl_ls_indices_pre)
            {
                SLEE_HDB_REC qh_data = mp_dbms->get_data(LAKDB_LEASES, qv_ls_index);
                if(qvl_ten_indices.contains(qh_data.value(FLD_LS_TINDEX)))
                    mqvl_indexes.append(qv_ls_index);
            }
        }
        else
            mqvl_indexes.append(qvl_ls_indices_pre);
    }
    else
    {
        if(qvl_ten_indices.size())
        {
            foreach(QVariant qv_t_index, qvl_ten_indices)
            {
                QVariantList qvl = mp_dbms->get_db(LAKDB_LEASES)->findDataEq(FLD_LS_TINDEX, qv_t_index);
                mqvl_indexes.append(qvl);
            }
        }
    }

//by dates filtering
    //if prev filter present
    if(mqvl_indexes.size() && p_filter->mqd_e.isValid() && p_filter->mqd_s.isValid())
    {
        QVariantList qvl_temp = mqvl_indexes;
        mqvl_indexes.clear();
        for(int i = 0; i < qvl_temp.size(); i ++)
        {
            bool s_ok = false;
            SLEE_HDB_REC qh_data = mp_dbms->get_data(LAKDB_LEASES, qvl_temp.at(i));
            if(p_filter->m_before_s)
                if(qh_data.value(FLD_LS_SDATE).toDate() <= p_filter->mqd_s) s_ok = true;
            if(!p_filter->m_before_s)
                if(qh_data.value(FLD_LS_SDATE).toDate() >= p_filter->mqd_s) s_ok = true;
            if(!s_ok) continue;
            bool e_ok = false;
            if(p_filter->m_before_e)
                if(qh_data.value(FLD_LS_EDATE).toDate() <= p_filter->mqd_e) e_ok = true;
            if(!p_filter->m_before_e)
                if(qh_data.value(FLD_LS_EDATE).toDate() >= p_filter->mqd_e) e_ok = true;
            if(!e_ok) continue;
            mqvl_indexes.append(qvl_temp.at(i));
        }
        return;
    }
   //if prev filter is not present
   if((p_filter->mqstr_street.isEmpty()) &&
           (p_filter->mqstr_house.isEmpty()) &&
           (p_filter->mqstr_ap_num.isEmpty()) &&
           (p_filter->mqstr_ten_fam.isEmpty()))
   {
       mqvl_indexes.clear();
       QVariantList qvl_s, qvl_e;
       QVariant qv_req = p_filter->mqd_s;
       if(p_filter->m_before_s)
           qvl_s = mp_dbms->get_db(LAKDB_LEASES)->findDataRange(FLD_LS_SDATE,NULL,true,&qv_req,true);
       if(!p_filter->m_before_s)
           qvl_s = mp_dbms->get_db(LAKDB_LEASES)->findDataRange(FLD_LS_SDATE,&qv_req,true);

       qv_req = p_filter->mqd_e;
       if(p_filter->m_before_e)
           qvl_e = mp_dbms->get_db(LAKDB_LEASES)->findDataRange(FLD_LS_EDATE,NULL,true,&qv_req,true);
       if(!p_filter->m_before_e)
           qvl_e = mp_dbms->get_db(LAKDB_LEASES)->findDataRange(FLD_LS_EDATE,&qv_req,true);

       foreach(QVariant qv_index, qvl_s)
       {
          if(qv_index.toULongLong() == 0ll) continue;
           if(qvl_e.contains(qv_index))
           mqvl_indexes.append(qv_index);
       }
   }
}

int LeasesModel::rowCount(const QModelIndex &/*parent*/) const
{
    return mqvl_indexes.size();
}

int LeasesModel::columnCount(const QModelIndex &/*parent*/) const
{
    //0 - number
    //1 - start-date
    //2 - apartment
    //3 - tenant
    //4 - space
    //5 - stop-reason
    //6 - comments

    return 7;
}

QVariant LeasesModel::data(const QModelIndex &index, int role) const
{
    static int last_row = -1;
    static SLEE_HDB_REC qh_data;
    if(role == -1)
    {
        last_row = -1;
        return QVariant();
    }
    if(!((role == Qt::DisplayRole) || (role==Qt::ToolTipRole))) return QVariant();
    int r = index.row();
    int c = index.column();
    if(last_row != r)
    {
        last_row = r;
        qh_data = mp_dbms->get_data(LAKDB_LEASES,mqvl_indexes.at(r));
    }
    QString qstr;
    switch(c)
    {
    case 0: qstr = qh_data.value(FLD_LS_NUM).toString();  break;
    case 1:  qstr = qh_data.value(FLD_LS_SDATE).toDate().toString("dd.MM.yyyy"); break;
    case 2: qstr = mp_dbms->get_apartment_info(qh_data.value(FLD_LS_AINDEX)); break;
    case 3: qstr = mp_dbms->get_tenant_fio(qh_data.value(FLD_LS_TINDEX));break;
    case 4: qstr = QString::number(mp_dbms->get_leases_space(qh_data)); break;
    case 5: qstr = qh_data.value(FLD_LS_REASON).toString(); break;
    case 6:  qstr = qh_data.value(FLD_LS_COMM).toString(); break;
    }
    return QVariant(qstr);
}

QVariant LeasesModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role != Qt::DisplayRole) return QVariant();
    if(orientation == Qt::Vertical)
        return QVariant(section+1);
    if(orientation != Qt::Horizontal) return QVariant();
    int c = section;
    QString qstr;
    switch(c)
    {
    case 0: qstr = RUSTR("Номер. ");  break;
    case 1:  qstr = RUSTR("Дата");  break;
    case 2: qstr = RUSTR("Жил.пом. ");  break;
    case 3: qstr = RUSTR("Наниматель ");  break;
    case 4: qstr = RUSTR("Аренд. пл. ");  break;
    case 5: qstr = RUSTR("Статус дог. ");  break;
    case 6: qstr = RUSTR("Комментарии ");  break;
    }
    return QVariant(qstr);
}


QVariant LeasesModel::get_db_index(const QModelIndex &mod_index)
{
    if(!mod_index.isValid()) return QVariant();
    return mqvl_indexes.at(mod_index.row());
}

QModelIndex LeasesModel::get_mod_index(const QVariant &qv_l_index)
{
    if(qv_l_index.isNull()) return QModelIndex();
    int row = mqvl_indexes.indexOf(qv_l_index);
    if(row < 0) return QModelIndex();
    return createIndex(row, 0);
}


void LeasesModel::update_data(const QModelIndex &mod_index)
{
    if(!mod_index.isValid()) return;
    data(QModelIndex(), -1);
}
